/*******************************************************************************
 * Copyright 2009 DCSpectrometer - http://code.google.com/p/dcspectrometer 
 *  
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * you may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 *  
 *     http://www.apache.org/licenses/LICENSE-2.0 
 *     
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License. 
 *******************************************************************************/
package com.dcspectrometer;

import java.awt.Color;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;

public class test {

  private static final String DEFAULT_SPECTRA_FOLDER = "/home/user/workspace/dcspectrometer/spectra/";
  private static final String DEFAULT_SPECTRA_FILENAME = "LED_spectra.csv";
  private static final String DEFAULT_IMAGE_FOLDER = "/home/user/workspace/dcspectrometer/samples/";
  private static final String DEFAULT_IMAGE_FILENAME = "DSC_8026.NEF"; //"DSC_0930.NEF"; //"DSC_8026.NEF"; //"DSC_6328.NEF";
  private static final double STOP_DIFFERENCE = 0.5;
  private static final double MINIMUM_THRESHOLD = 100;
  private static final int DETECTOR_SIZE = 20;

  public static void main(String[] args) {

    /** STEP 1: Load 16-bit RAW image */
    System.out.println("Loading image ...");
    Raster raster = null;
    BufferedImage image = null;
    try {
      image = ImageLoader.getImage(DEFAULT_IMAGE_FOLDER + DEFAULT_IMAGE_FILENAME);
      raster = image.getData();
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
      return;
    } catch (IOException e) {
      e.printStackTrace();
      return;
    }

    RasterTileStatistics stats = new RasterTileStatistics(raster);
    System.out.println("Image info:");
    System.out.println("\tsize = " + stats.getHeight() + " x " + stats.getWidth());
    System.out.println("\tchannels = " + stats.getChannelCount());
    System.out.println("\t" + stats.toString(ImageStatistics.RED_CHANNEL, "red"));
    System.out.println("\t" + stats.toString(ImageStatistics.GREEN_CHANNEL, "green"));
    System.out.println("\t" + stats.toString(ImageStatistics.BLUE_CHANNEL, "blue"));
    
    /** STEP 2: Find LED edges (using luminosity edge detector). */
    System.out.println("Finding edges ...");
    Detector edgeDetector = new EdgeDetector(MINIMUM_THRESHOLD, STOP_DIFFERENCE);
    ArrayList<Point> edges = edgeDetector.getFeatures(image, DETECTOR_SIZE, DETECTOR_SIZE);

    // Temporary to check what features were picked up.
    try {
      BufferedImage detectedImage = edgeDetector.showFeatures(image, DETECTOR_SIZE, DETECTOR_SIZE,
          Color.RED.getRGB());
      ImageLoader.saveTiff(DEFAULT_IMAGE_FOLDER + "temp.TIFF", detectedImage);
    } catch (IOException e) {
      e.printStackTrace();
      return;
    }

    /** STEP 3: Find local maxima (using Gradient Descend algorithm and K-mean algorithm). */
    System.out.println("Looking for maxima ...");
    HashMap<Point, int[]> maxima = ImageAnalyser.getMaxima(image, edges);

    for (Point point : maxima.keySet()) {
      int[] color = maxima.get(point);
      System.out.println("\tPoint(x, y) = " + "(" + point.x + "," + point.y + "), RGB = " + "("
          + color[0] + ", " + color[1] + ", " + color[2] + ")");
    }

    /**
     * STEP 4: Map local maxima to known LED pattern to determine wavelength of each maxima (using
     * topological pattern matching).
     */
    System.out.println("Finding mapping ...");
    HashMap<String, int[]> ledMaping = null;
    ledMaping = ImageAnalyser.getLEDMapping(raster, maxima);

    for (String wavelength : ledMaping.keySet()) {
      int[] color = ledMaping.get(wavelength);
      System.out.println("\tLED = " + wavelength + ", RGB = " + "(" + color[0] + ", " + color[1]
          + ", " + color[2] + ")");
    }

    /** STEP 5: Construct Response Curve */
    System.out.println("Constructing response curve ...");
    SensorResponseCurve responseCurve = null;
    try {
      responseCurve = new SensorResponseCurve(ledMaping,
          DEFAULT_SPECTRA_FOLDER + DEFAULT_SPECTRA_FILENAME);
    } catch (IllegalArgumentException e) {
      e.printStackTrace();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    //System.out.println(responseCurve);

    
    /** STEP 6: Spectrometer analysis of the input - will be implemented at a later date */

    /** STEP 7: Determine experimental accuracy - will be implemented at a later date */

  }
}
